package xendit

import (
	"encoding/json"
	"errors"
	"log/slog"

	"gitee.com/gxcc/go-utils/utils"
)

type RecurringCreateRequest struct {
	ExternalId          string `json:"external_id"`
	PayerEmail          string `json:"payer_email"`
	Description         string `json:"description"`
	Amount              int64  `json:"amount"`
	Interval            string `json:"interval"`
	IntervalCount       int    `json:"interval_count"`
	TotalRecurrence     int    `json:"total_recurrence"`
	InvoiceDuration     int    `json:"invoice_duration"`
	ShouldSendEmail     bool   `json:"should_send_email"`
	MissedPaymentAction string `json:"missed_payment_action"`
	CreditCardToken     string `json:"credit_card_token"`
	StartDate           string `json:"start_date,omitempty"`
	Recharge            bool   `json:"recharge"`
	ChargeImmediately   bool   `json:"charge_immediately"`
	//SuccessRedirectUrl  string `json:"success_redirect_url"`
	//FailureRedirectUrl  string `json:"failure_redirect_url"`
}

type RecurringRecord struct {
	Id                  string `json:"id" gorm:"primary_key"`
	User                string `json:"user_id"`
	ExternalId          string `json:"external_id"`
	Status              string `json:"status"`
	Amount              int64  `json:"amount"`
	PayerEmail          string `json:"payer_email"`
	Description         string `json:"description"`
	Interval            string `json:"interval"`
	IntervalCount       int    `json:"interval_count"`
	TotalRecurrence     int    `json:"total_recurrence"`
	RecurrenceProgress  int    `json:"recurrence_progress"`
	InvoiceDuration     int64  `json:"invoice_duration"`
	ShouldSendEmail     string `json:"should_send_email"`
	MissedPaymentAction string `json:"missed_payment_action"`
	RecurringPaymentUrl string `json:"recurring_payment_url"`
	CreditCardToken     string `json:"credit_card_token"`
	Created             string `json:"created"`
	Updated             string `json:"updated"`
	Recharge            bool   `json:"recharge"`
	CardNumber          string `json:"cardNumber"`
	CardMonth           string `json:"cardMonth"`
	CardYear            string `json:"cardYear"`
}

func (RecurringRecord) TableName() string {
	return "xen_recurring_payment"
}

func (svc *XenditSvc) CreateRecurringPayment(requestParams RecurringCreateRequest,
	cardNumber string, cardMonth string, cardYear string) (RecurringRecord, error) {
	url := "https://api.xendit.co/recurring_payments"
	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	req, err := json.Marshal(requestParams)
	if err != nil {
		return RecurringRecord{}, errors.New("generate recurring create request body failed")
	}

	res, err := utils.HttpPost(url, headers, req)
	if err != nil {
		return RecurringRecord{}, errors.New("create recurring failed")
	}

	slog.Debug(string(res.Body))

	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		return RecurringRecord{}, errors.New(resMap["error_code"])
	}
	var record RecurringRecord
	json.Unmarshal(res.Body, &record)

	// 记录本次支付的银行卡号等信息
	record.CardNumber = cardNumber
	record.CardMonth = cardMonth
	record.CardYear = cardYear

	// 保存信息
	//if err := app.DB.Create(&record).Error; err != nil {
	//	slog.Error(err.Error())
	//	return record, err
	//}

	return record, nil
}

type RecurringEditRequest struct {
	Amount              int64  `json:"amount,omitempty"`
	CreditCardToken     string `json:"credit_card_token,omitempty"`
	Interval            string `json:"interval,omitempty"`
	IntervalCount       int    `json:"interval_count,omitempty"`
	InvoiceDuration     int    `json:"invoice_duration,omitempty"`
	ShouldSendEmail     bool   `json:"should_send_email,omitempty"`
	MissedPaymentAction string `json:"missed_payment_action,omitempty"`
}

func (svc *XenditSvc) EditRecurringPayment(recurringId string, requestParams RecurringEditRequest) (RecurringRecord, error) {
	url := "https://api.xendit.co/recurring_payments/" + recurringId
	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	req, err := json.Marshal(requestParams)
	if err != nil {
		return RecurringRecord{}, errors.New("generate recurring update request body failed")
	}

	res, err := utils.HttpPatch(url, headers, req)
	if err != nil {
		return RecurringRecord{}, errors.New("update recurring failed")
	}
	slog.Debug(string(res.Body))

	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		return RecurringRecord{}, errors.New(resMap["error_code"])
	}
	var record RecurringRecord
	json.Unmarshal(res.Body, &record)

	// 保存信息
	//var omitColumns = []string{"card_number", "card_month", "card_year"}
	//if err := app.DB.Omit(omitColumns...).Save(&record).Error; err != nil {
	//	slog.Error(err.Error())
	//	return record, err
	//}

	return record, nil
}

func (svc *XenditSvc) StopRecurringPayment(recurringId string) (RecurringRecord, error) {
	url := "https://api.xendit.co/recurring_payments/" + recurringId + "/stop!"
	slog.Debug(url)

	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	res, err := utils.HttpPost(url, headers, nil)
	if err != nil {
		slog.Error(err.Error())
		return RecurringRecord{}, errors.New("stop recurring failed")
	}
	slog.Debug(string(res.Body))

	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		//if resMap["error_code"] == "NOT_FOUND_ERROR" {
		//	// 查找本地保存的RecurringRecord
		//	var record RecurringRecord
		//	if err := app.DB.Where("id = ?", recurringId).First(&record).Error; err != nil {
		//		return RecurringRecord{}, errors.New(resMap["error_code"])
		//	}
		//	// 查看本地记录的状态，如果不是STOPPED状态，则修改为STOPPED状态
		//	if record.Status != "STOPPED" {
		//		var updated = time.Now().Format(time.RFC3339)
		//		app.DB.Model(&record).Updates(map[string]any{
		//			"status":  "STOPPED",
		//			"updated": updated,
		//		})
		//		record.Status = "STOPPED"
		//		record.Updated = updated
		//	}
		//	return record, nil
		//} else {
		if len(resMap["message"]) > 0 {
			return RecurringRecord{}, errors.New(resMap["message"])
		} else {
			return RecurringRecord{}, errors.New(resMap["error_code"])
		}
		//}
	} else {
		var record RecurringRecord
		json.Unmarshal(res.Body, &record)

		// 保存信息
		//var omitColumns = []string{"card_number", "card_month", "card_year"}
		//if err := app.DB.Omit(omitColumns...).Save(&record).Error; err != nil {
		//	slog.Error(err.Error())
		//	return record, err
		//}
		return record, nil
	}
}

func (svc *XenditSvc) PauseRecurringPayment(recurringId string) (RecurringRecord, error) {
	url := "https://api.xendit.co/recurring_payments/" + recurringId + "/pause!"
	slog.Debug(url)

	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	res, err := utils.HttpPost(url, headers, nil)
	if err != nil {
		slog.Error(err.Error())
		return RecurringRecord{}, errors.New("pause recurring failed")
	}
	slog.Debug(string(res.Body))

	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		if len(resMap["message"]) > 0 {
			return RecurringRecord{}, errors.New(resMap["message"])
		} else {
			return RecurringRecord{}, errors.New(resMap["error_code"])
		}
	} else {
		var record RecurringRecord
		json.Unmarshal(res.Body, &record)

		// 保存信息
		//var omitColumns = []string{"card_number", "card_month", "card_year"}
		//if err := app.DB.Omit(omitColumns...).Save(&record).Error; err != nil {
		//	slog.Error(err.Error())
		//	return record, err
		//}
		return record, nil
	}
}

func (svc *XenditSvc) ResumeRecurringPayment(recurringId string) (RecurringRecord, error) {
	url := "https://api.xendit.co/recurring_payments/" + recurringId + "/resume!"
	slog.Debug(url)

	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	res, err := utils.HttpPost(url, headers, nil)
	if err != nil {
		slog.Error(err.Error())
		return RecurringRecord{}, errors.New("resume recurring failed")
	}
	slog.Debug(string(res.Body))

	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		if len(resMap["message"]) > 0 {
			return RecurringRecord{}, errors.New(resMap["message"])
		} else {
			return RecurringRecord{}, errors.New(resMap["error_code"])
		}
	} else {
		var record RecurringRecord
		json.Unmarshal(res.Body, &record)

		// 保存信息
		//var omitColumns = []string{"card_number", "card_month", "card_year"}
		//if err := app.DB.Omit(omitColumns...).Save(&record).Error; err != nil {
		//	slog.Error(err.Error())
		//	return record, err
		//}
		return record, nil
	}
}

func (svc *XenditSvc) GetRecurringPayment(recurringId string) (RecurringRecord, error) {
	url := "https://api.xendit.co/recurring_payments/" + recurringId
	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	res, err := utils.HttpGet(url, headers)
	if err != nil {
		return RecurringRecord{}, errors.New("stop recurring failed")
	}
	slog.Debug(string(res.Body))

	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		return RecurringRecord{}, errors.New(resMap["error_code"])
	}
	var record RecurringRecord
	json.Unmarshal(res.Body, &record)

	// 保存信息
	//var omitColumns = []string{"card_number", "card_month", "card_year"}
	//if err := app.DB.Omit(omitColumns...).Save(&record).Error; err != nil {
	//	slog.Error(err.Error())
	//	return record, err
	//}

	return record, nil
}
